[アップデート]AWS ワークロードのネットワークパフォーマンスを監視するCloudWatch Network Monitoring Flow Monitorsが発表されました #AWSreInvent

[アップデート]AWS ワークロードのネットワークパフォーマンスを監視するCloudWatch Network Monitoring Flow Monitorsが発表されました #AWSreInvent

Clock Icon2024.12.04

re:Invent2024に参加している。たかやまです。

CloudWatchで、新たにAWSワークロードのネットワークパフォーマンスを監視できるフローモニターがリリースされました。

https://aws.amazon.com/jp/about-aws/whats-new/2024/12/amazon-cloudwatch-network-monitoring-workloads-monitors/

Network Flow Monitors とは

概要 :
Network Flow Monitors を使用すると、VPC ネットワーク内の TCP ベースのトラフィックで発生するレイテンシとパケット損失に関するほぼリアルタイムのメトリクスを取得できるようになります。これらのメトリクスを見ることで、ワークロードトラフィックのネットワーク問題の追跡および調査に活用することができます。

また、AWS ワークロードでネットワークの劣化が発生した場合、Network Flow Monitors を使用することで、問題の原因がアプリケーションのワークロードにあるか、基盤となる AWS インフラストラクチャにあるかを判断することも可能になります。

Flow Monitorの監視項目 :

  • Agents
  • Top contributors
  • Local and remote resources
  • Workload insights
  • Monitors
  • Network health indicator (NHI)
  • Scope
  • Query ID
  • Performance metricss

詳細 : Components and features of Network Flow Monitor - Amazon CloudWatch

料金 :
Network Flow Monitorsは利用する監視リソースとCloudWatchメトリクスごとに料金が発生します。

詳細についてはAmazon CloudWatch 料金の「Network Monitoring」 > 「Flow Monitor」を確認してください。

やってみる

Network Flow Monitorsを有効にする

デフォルトでは有効化されていないので「ネットワークモニタリング」 > 「フローモニター」から、サービスロールの追加に問題がなければネットワークフローモニターを有効にするを選択します。

CleanShot 2024-12-03 at 08.24.19@2x-1-1.png

私の環境ではステータスが「保留中」のまま、5分程度かかりました。

CleanShot 2024-12-03 at 08.35.20@2x-1.png

有効化が完了すると、以下のように表示されます。
CleanShot 2024-12-03 at 08.40.31@2x.png

サンプルアプリケーションをデプロイとエージェントインストール

次に診断対象となるシンプルなマルチAZのEC2のWebサイトをCDKで作成します。

CDKコード
#!/usr/bin/env node
import * as cdk from 'aws-cdk-lib';
import * as ec2 from 'aws-cdk-lib/aws-ec2';
import * as elbv2 from 'aws-cdk-lib/aws-elasticloadbalancingv2';
import * as targets from 'aws-cdk-lib/aws-elasticloadbalancingv2-targets';
import * as iam from 'aws-cdk-lib/aws-iam';
import { Construct } from 'constructs';
import 'source-map-support/register';

class MultiAzEc2Stack extends cdk.Stack {
  constructor(scope: Construct, id: string, props?: cdk.StackProps) {
    super(scope, id, props);

    const vpc = new ec2.Vpc(this, 'MyVPC', {
      maxAzs: 2,
      subnetConfiguration: [
        {
          cidrMask: 24,
          name: 'Public',
          subnetType: ec2.SubnetType.PUBLIC,
        }
      ],
    });
    const vpcEndpoints = new ec2.InterfaceVpcEndpoint(this, 'SSMEndpoint', {
      vpc,
      service: ec2.InterfaceVpcEndpointAwsService.SSM,
      subnets: { subnetType: ec2.SubnetType.PUBLIC },
      privateDnsEnabled: true,
    });

    new ec2.InterfaceVpcEndpoint(this, 'SSMMessagesEndpoint', {
      vpc,
      service: ec2.InterfaceVpcEndpointAwsService.SSM_MESSAGES,
      subnets: { subnetType: ec2.SubnetType.PUBLIC },
      privateDnsEnabled: true,
    });

    new ec2.InterfaceVpcEndpoint(this, 'EC2MessagesEndpoint', {
      vpc,
      service: ec2.InterfaceVpcEndpointAwsService.EC2_MESSAGES,
      subnets: { subnetType: ec2.SubnetType.PUBLIC },
      privateDnsEnabled: true,
    });

    const ec2SecurityGroup = new ec2.SecurityGroup(this, 'EC2SecurityGroup', {
      vpc,
      description: 'Security group for EC2 instances',
      allowAllOutbound: true,
    });

    const albSecurityGroup = new ec2.SecurityGroup(this, 'ALBSecurityGroup', {
      vpc,
      description: 'Security group for ALB',
      allowAllOutbound: true,
    });

    ec2SecurityGroup.addIngressRule(
      albSecurityGroup,
      ec2.Port.tcp(80),
      'Allow HTTP access from ALB'
    );

    albSecurityGroup.addIngressRule(
      ec2.Peer.anyIpv4(),
      ec2.Port.tcp(80),
      'Allow HTTP access from internet'
    );

    const role = new iam.Role(this, 'EC2Role', {
      assumedBy: new iam.ServicePrincipal('ec2.amazonaws.com'),
    });

    role.addManagedPolicy(
      iam.ManagedPolicy.fromAwsManagedPolicyName('AmazonSSMManagedInstanceCore')
    );

    const alb = new elbv2.ApplicationLoadBalancer(this, 'MyALB', {
      vpc,
      internetFacing: true,
      securityGroup: albSecurityGroup,
    });

    const targetGroup = new elbv2.ApplicationTargetGroup(this, 'MyTargetGroup', {
      vpc,
      port: 80,
      protocol: elbv2.ApplicationProtocol.HTTP,
      targetType: elbv2.TargetType.INSTANCE,
      healthCheck: {
        path: '/',
        healthyHttpCodes: '200',
        interval: cdk.Duration.seconds(30),
        timeout: cdk.Duration.seconds(5),
      },
    });

    alb.addListener('Listener', {
      port: 80,
      defaultTargetGroups: [targetGroup],
    });

    vpc.publicSubnets.forEach((subnet, index) => {
      const ec2Instance = new ec2.Instance(this, `EC2Instance-${index + 1}`, {
        vpc,
        vpcSubnets: {
          subnets: [subnet],
        },
        instanceType: ec2.InstanceType.of(
          ec2.InstanceClass.T3,
          ec2.InstanceSize.MICRO
        ),
        machineImage: new ec2.AmazonLinuxImage({
          generation: ec2.AmazonLinuxGeneration.AMAZON_LINUX_2023
        }),
        securityGroup: ec2SecurityGroup,
        role: role,
      });

      ec2Instance.userData.addCommands(
        'yum update -y',
        'yum install -y httpd',
        'systemctl start httpd',
        'systemctl enable httpd',
        `echo "<h1>Hello from AZ ${subnet.availabilityZone}</h1>" > /var/www/html/index.html`
      );

      targetGroup.addTarget(new targets.InstanceTarget(ec2Instance));
    });

    new cdk.CfnOutput(this, 'AlbDnsName', {
      value: alb.loadBalancerDnsName,
      description: 'The DNS name of the load balancer',
    });
  }
}

const app = new cdk.App();
new MultiAzEc2Stack(app, 'MultiAzEc2Stack', {
  env: {
    region: 'ap-northeast-1',
  },
});

こちらの手順を参考にコンソールからAWS Network Flow Monitoring Agentのインストールを行います。

https://docs.aws.amazon.com/AmazonCloudWatch/latest/monitoring/CloudWatch-NetworkFlowMonitor-agents-ec2.html

Systems Managerの「ディストリビューター」から AmazonCloudWatchNetworkFlowMonitorAgentドキュメントを検索します。

今回は「1回限りのインストール」を実施します。

CleanShot 2024-12-03 at 20.22.53@2x.png

対象のインスタンス2台を指定して実行します。

CleanShot 2024-12-03 at 20.26.58@2x.png

全体的なステータスが「成功」になればインストール完了です。

CleanShot 2024-12-03 at 22.12.16@2x.png

今回はAmazon Linux 2023でためしていますが、別のAmazon Linux 2ではインストールが失敗したので現時点ではインストール対象となるOSが制限されている可能性があります。
(ドキュメント上では確認できず)

モニターを作成する

次にNetwork Flow Monitors側でモニターを作成します。

ためしにAvailability Zone内のすべてのネットワークを監視するモニターを作成してみます。

CleanShot 2024-12-03 at 09.42.35@2x-1.png

作成できると以下のようなモニターが作成されます。
現在は問題なくアクセスできるのでネットワークヘルスインジケーターは「正常」になっています。

CleanShot 2024-12-03 at 22.27.27@2x.png

ここで作成したアプリケーション内で100msの遅延と5%のパケットロスをさせてみます。

# iproute-tcパッケージのインストール
sudo dnf install iproute-tc

# ネットワークインターフェース名の確認
ip addr show

# 実行コマンド
sudo tc qdisc add dev ens5 root netem delay 100ms loss 20%

想定ではネットワークヘルスインジケーターあたりが「異常」になるかと思いますが、そういうわけではないようです...(そもそものトラフィックの概要が表示されなくなった?)

CleanShot 2024-12-03 at 23.05.02@2x.png

このあたりの動作については今後深堀りしていければと思います。

付録 : できなかったEKSでのNetwork Flow Monitors

モニターを作成する前に、モニタリングするアプリケーションとしてOne Observability Workshopのサンプルアプリケーションをデプロイしたいと思います。

CloudShellで以下のコマンド実行します。

curl -O https://raw.githubusercontent.com/aws-samples/one-observability-demo/main/codepipeline-stack.yaml

aws cloudformation create-stack --stack-name Observability-Workshop \
  --template-body file://codepipeline-stack.yaml \
  --capabilities CAPABILITY_NAMED_IAM \
  --parameters ParameterKey=UserRoleArn,ParameterValue=$(aws iam get-role --role-name $(aws sts get-caller-identity --query Arn --output text | awk -F/ '{print $(NF-1)}') --query Role.Arn --output text) 

デプロイが完了するとスタック「Services」の「PetSiteUrl」から以下のようなPet Adoptionのサイトを確認することができます。

CleanShot 2024-12-03 at 10.57.45@2x-1.png
CleanShot 2024-12-03 at 10.54.20@2x-3.png

全体のアーキテクチャは以下のようになっています。
こちらのEKSクラスターに、エージェントをインストールしていきたいと思います。

PetAdoptions_architecture.png
引用 : One Observability Workshop

こちらの手順を参考にコンソールからAWS Network Flow Monitoring Agentのインストールを行います。

https://docs.aws.amazon.com/AmazonCloudWatch/latest/monitoring/CloudWatch-NetworkFlowMonitor-agents-kubernetes-eks.html#CloudWatch-NetworkFlowMonitor-agents-kubernetes-eks-console

EKSクラスターの「アドオンをさらに追加」から「AWS Network Flow Monitoring Agent」をインストールします。

CleanShot 2024-12-03 at 11.23.56@2x-1.png
CleanShot 2024-12-03 at 11.25.54@2x-1.png

アドオン設定では今回は「推奨ロールを作成」を使ってロールを作っていきたいと思います。
CleanShot 2024-12-03 at 11.28.01@2x.png

「EKS - Pod Identity」に対して CloudWatchNetworkFlowMonitorAgentPublishPolicyポリシーをアタッチします。

CleanShot 2024-12-03 at 11.29.31@2x-1.png
CleanShot 2024-12-03 at 11.30.46@2x.png

さきほどの画面で作成したAmazonEKSPodidentityAWSNetworkFlowMonitoringAgentRoleを付与します。
CleanShot 2024-12-03 at 11.31.51@2x.png

こちらの設定でアドオンを追加します。
CleanShot 2024-12-03 at 11.32.54@2x.png

追加しましたが、以下のエラーが発生していました...

Amazon EKS Pod Identity agent is not installed in the cluster. To use EKS Pod Identity to grant AWS permissions to pods through Kubernetes service accounts, install the Amazon EKS Pod Identity agent

CleanShot 2024-12-03 at 12.49.26@2x-1.png

エラーメッセージに従いAmazon EKS Pod Identity Agentをインストールします。

CleanShot 2024-12-03 at 12.54.52@2x-1.png
CleanShot 2024-12-03 at 12.59.32@2x-1.png

そのうえでなお、情報収集はされなかったので、今回はここで断念しました...
(社内でも試したメンバーがいましたが、同様の結果でした)

CleanShot 2024-12-03 at 11.34.29@2x.png

最後に

CloudWatch Network Flow Monitorsを紹介しました。

検証したうえで、機能として安定していなさそうな部分や正直未知数な部分もあるので、このあたりは今後も検証をつづけていけたらと思います。

この記事が誰かのお役に立てれば幸いです。

以上、たかやま(@nyan_kotaroo)でした。

Share this article

facebook logohatena logotwitter logo

© Classmethod, Inc. All rights reserved.